﻿using DotNetExtensions.Core.IOC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CoreSimple.IOC
{
    public class IOC_Simple
    {
        public IOC_Simple()
        {

            var start = DateTime.Now;

            ContainerBuilder builder = ContainerBuilder.Default;

            builder.RegistTypes(option =>
            {
                option.Assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies());
                option.Filters.Add(new InjectTypeFilter
                {
                    Kind = InjectKind.Named,
                    Type = typeof(IProvider)
                });
            });

            Console.WriteLine($"{(DateTime.Now -start).TotalMilliseconds}/ms");

            Timer timer = new Timer(new TimerCallback(obj =>
            {
                var provider = builder.Resolve<IProvider>();
                provider.Write();
                var provider2 = builder.Resolve<IProvider2>();
                provider2.Write();
                //var provider3 = builder.Resolve<Provider3>();
                //provider3.Write();
                var provider31 = builder.ResolveNamed<Provider3>("CoreSimple.IOC.Provider3");
                provider31.Write();
                // 如果不指定名称 则使用类全名称 = typeof(Provider1).FullName
                //var provider2 = builder.ResolveNamed<IProvider>("Provider1");
                //provider2.Write();

                //var provider1 = builder.ResolveNamed<IProvider>("Provider2");
                //provider1.Write();

                object fullname1 = builder.Resolve("CoreSimple.IOC.FullNmaeTest");
                object fullname2 = builder.Resolve("CoreSimple.IOC.FullNmaeTestSingle");

                (fullname1 as FullNmaeTest).Hello();
                (fullname2 as FullNmaeTestSingle).Hello();

            }), null, 1000, 1000);
        }
    }
    public interface IProvider : IAutoInject
    {
        void Write();
    }
    
    [AutoInject(Kind = InjectKind.Typed)]
    public interface IProvider2
    {
        void Write();
    }

    public class Provider1 : IProvider
    {
        public void Write()
        {
            Console.WriteLine("I'm is provider 1");
        }
    }
    
    public class Provider2 : IProvider2
    {
        public void Write()
        {
            Console.WriteLine("I'm is provider 2");
        }
    }
    
    [AutoInject(InjectKind.Named)]
    public class Provider3
    {
        public void Write()
        {
            Console.WriteLine("I'm is provider 3");
        }
    }

    
    [AutoInject]
    public class FullNmaeTest
    {
        public FullNmaeTest()
        {

        }

        public void Hello()
        {
            Console.WriteLine("Hello im FullNmaeTest");
        }
    }
    [Inject(Scope = InjectScope.Single)]
    [AutoInject]
    public class FullNmaeTestSingle
    {
        private readonly DateTime now;
        public FullNmaeTestSingle()
        {
            now = DateTime.Now;
        }

        public void Hello()
        {
            Console.WriteLine($"{now}:Hello im FullNmaeTestSingle");
        }
    }
}
